<?php
namespace WDB\Wrapper;
use WDB;

/**
 * Generic database column
 *
 * @author Richard Ejem <richard(at)ejem.cz>
 * @package WDB
 */
class Column extends AbstractColumn implements iDBColumn
{

    /**@var WDB\Analyzer\Column*/
    protected $columnAnalyzer;

    /**@var string*/
    protected $webUIClass = NULL;

    public function __construct($tableWrapper, $columnAnalyzer)
    {
        $this->columnAnalyzer = $columnAnalyzer;
        parent::__construct($tableWrapper);
        $this->fetchValidationRules($this->rules);
    }

    protected function fetchValidationRules(WDB\Validation\ColumnRules $rules)
    {
        $this->columnAnalyzer->fetchValidationRules($rules);
        if (isset($this->columnAnalyzer->getAnnotations()->minlength))
        {
            $rules->minLength($this->columnAnalyzer->getAnnotations()->last('minlength')->getText());
        }
        if (isset($this->columnAnalyzer->getAnnotations()->maxlength))
        {
            $rules->maxLength($this->columnAnalyzer->getAnnotations()->last('maxlength')->getText());
        }
        if (isset($this->columnAnalyzer->getAnnotations()->minvalue))
        {
            $rules->minValue($this->columnAnalyzer->getAnnotations()->last('minvalue')->getText());
        }
        if (isset($this->columnAnalyzer->getAnnotations()->maxvalue))
        {
            $rules->maxValue($this->columnAnalyzer->getAnnotations()->last('maxvalue')->getText());
        }
        if (isset($this->columnAnalyzer->getAnnotations()->required))
        {
            $rules->required();
        }
        if (isset($this->columnAnalyzer->getAnnotations()->integer))
        {
            $rules->integer();
        }
        if (isset($this->columnAnalyzer->getAnnotations()->float))
        {
            $rules->float();
        }
        if (isset($this->columnAnalyzer->getAnnotations()->equals))
        {
            $rules->equals($this->columnAnalyzer->getAnnotations()->last('equals')->getText());
        }
        if (isset($this->columnAnalyzer->getAnnotations()->pattern))
        {
            $rules->pattern($this->columnAnalyzer->getAnnotations()->last('pattern')->getText());
        }
        if (isset($this->columnAnalyzer->getAnnotations()->email))
        {
            $rules->email();
        }
        if (isset($this->columnAnalyzer->getAnnotations()->url))
        {
            $rules->url();
        }
    }

    public function setFieldValue($value)
    {
        return $this->columnAnalyzer->setFieldValue($value);
    }

    public function getStringValue($value)
    {
        return $value === NULL ? "=NULL" : preg_replace('~^=NULL~', '==NULL', $this->columnAnalyzer->getStringValue($value));
    }

    // <editor-fold defaultstate="collapsed" desc="iDBColumn implementation">
    public  function getName()
    {
        return $this->columnAnalyzer->getName();
    }

    public  function getTitle()
    {
        return $this->columnAnalyzer->getTitle();
    }

    public function getDefault()
    {
        return $this->columnAnalyzer->getDefault();
    }

    public function isNullable()
    {
        return $this->columnAnalyzer->isNullable();
    }

    public function getWebUIClass()
    {
        $c = $this->columnAnalyzer->getWebUIClass();
        if ($c === NULL)
        {
            return $this->webUIClass;
        }
        return $c;
    }
    public function getWebUIDisplayMode($original = NULL)
    {
        return parent::getWebUIDisplayMode($this->columnAnalyzer->getWebUIDisplayMode($original));
    }
    public function isAutoColumn()
    {
        return $this->columnAnalyzer->isAutoColumn();
    }
    public function isAutoIncrement()
    {
        return $this->columnAnalyzer->isAutoIncrement();
    }

    public function valueToDatatype($value)
    {
        return $this->columnAnalyzer->valueToDatatype($value);
    }
    public function fetchReadFields(&$fields)
    {
        $fields[] = new WDB\Query\Element\SelectField($this->columnAnalyzer->getIdentifier());
    }

    public function isOrderable()
    {
        return TRUE;
    }

    public function isFilterable()
    {
        return TRUE;
    }

    public function sortDatasource(WDB\iDatasource $datasource, $asc = TRUE, $prepend = TRUE)
    {
        $datasource->sort($this->getName(), $asc, $prepend);
    }


    public function filterDatasource(WDB\iDatasource $datasource, $value)
    {
        if (is_string($value) && $value{0} == '~')
        {
            $value = unserialize($value);
        }
        if (!$value instanceof WDB\Query\Element\Datatype\iDatatype)
        {
            $value = $this->columnAnalyzer->valueToDatatype($value);
        }
        $datasource->filter(WDB\Structure\FilterRule::create($this->columnAnalyzer->getIdentifier(), $value));
    }

    public function getFilterOptions()
    {
        $options = array();
        foreach ($this->table->getDatasource()->select($this->name)->distinct()->run() as $row)
        {
            $val = $row[$this->name];
            if ((!is_string($val) || $val{0} == '~') && !is_int($val))
            {
                $val = '~'.serialize($val);
            }
            $options[$val] = $row[$this->name];
        }
        return $options;
    }

    // </editor-fold>
}